`timescale 1ns/1ps

`include "gpu_bus.sv"

module tb;

parameter DATA_WIDTH = 64;
parameter ADDR_WIDTH = 32;    

logic clk;
logic rst_n;
reg [31:0] x;
logic [31:0] y;
logic [31:0] z;
logic [31:0] s;
logic [31:0] t;
logic [31:0] matrix_A;
logic [31:0] matrix_B;
logic [31:0] matrix_C;
logic [31:0] matrix_D;
logic [31:0] matrix_E;
logic [31:0] matrix_F;
logic [31:0] matrix_G;
logic [31:0] matrix_H;
logic [31:0] fog_x;
logic [31:0] fog_y;
logic [31:0] fog_z;
logic [7:0] r;
logic [7:0] g;
logic [7:0] b;
logic [7:0] a;
logic fragment_valid;
logic [31:0] tex_addr;
logic [31:0] tex_width;
logic [31:0] tex_height;
logic [1:0]  wrap_mode_s;
logic [1:0]  wrap_mode_t;
logic              bus_cmd  ;
logic      [5:0]   bus_bl   ;

logic              bus_den;
logic  fragment_tex_shading_busy;
logic  [31:0] x_out;
logic  [31:0] y_out;
logic  [31:0] z_out;
logic  [31:0] fog_x_out;
logic  [31:0] fog_y_out;
logic  [31:0] fog_z_out;
logic  [7:0] r_out;
logic  [7:0] g_out;
logic  [7:0] b_out;
logic  [7:0] a_out;
logic  [7:0] r_tex_out;
logic  [7:0] g_tex_out;
logic  [7:0] b_tex_out;
logic  [7:0] a_tex_out;
logic  fragment_out_valid;
logic l2_cache_busy;
logic [31:0]  ram_addr;
logic         ram_wrn;
logic         ram_csn;
logic [127:0] ram_wdata;
logic [127:0] ram_rdata ;
reg busy_buffer;


always@(posedge clk or negedge rst_n)
    begin
       if(~rst_n)
           busy_buffer <= 0;
       else
           busy_buffer <= $urandom_range(1'b0,1'b1);
    end

gpu_bus #(.ADDR_WIDTH(32), .DATA_WIDTH(128), .ID_WIDTH(1), .BL_WIDTH(8)) sink[4]();  
gpu_bus #(.ADDR_WIDTH(32), .DATA_WIDTH(128), .ID_WIDTH(3), .BL_WIDTH(8)) src();  



gpu_bus_matrix_core #
(
    .PORT_NUM  (4),
    .PORT_WIDTH(2),
    .ADDR_WIDTH(32),
    .DATA_WIDTH(128),
    .ID_WIDTH  (1  ),
    .BL_WIDTH  (8  ),
    .CMD_DEPTH (2)
) u_disp_bus_matrix
(
	.clk   (clk),
	.rst_n (rst_n),
    .sink  (sink),
    .source(src)
);      

gpu_bus_slave #(
    .DSIZE     (128),
    .ASIZE     (26),
    .ADDR_WIDTH(32),
    .ID_WIDTH  (4),
    .BL_WIDTH  (8)
) gpu_slave
(
    .clk      (clk      ),
    .rst_n    (rst_n    ),
    .sink     (src      ),
    .ram_addr (ram_addr ),
    .ram_wrn  (ram_wrn  ),
    .ram_csn  (ram_csn  ),
    .ram_wdata(ram_wdata),
    .ram_rdata(ram_rdata)

);             





fragment_tex_shading #(
    .CACHE_ADDR_BITS(ADDR_WIDTH),
    .CACHE_BUS_WIDTH(DATA_WIDTH)
) u_dut
(
.clk(clk),
.rst_n(rst_n),
.busy_in(busy_buffer),
.x(x),
.y(y),
.z(z),
.s(s),
.t(t),
.matrix_A(matrix_A),
.matrix_B(matrix_B),
.matrix_C(matrix_C),
.matrix_D(matrix_D),
.matrix_E(matrix_E),
.matrix_F(matrix_F),
.matrix_G(matrix_G),
.matrix_H(matrix_H),
.fog_x(fog_x),
.fog_y(fog_y),
.fog_z(fog_z),
.r(r),
.g(g),
.b(b),
.a(a),
.fragment_valid(fragment_valid),

.tex_addr(tex_addr),
.tex_width(tex_width),
.tex_height(tex_height),
.wrap_mode_s(wrap_mode_s),
.wrap_mode_t(wrap_mode_t),

.fragment_tex_shading_busy(fragment_tex_shading_busy),
.x_out(x_out),
.y_out(y_out),
.z_out(z_out),
.fog_x_out(fog_x_out),
.fog_y_out(fog_y_out),
.fog_z_out(fog_z_out),
.r_out(r_out),
.g_out(g_out),
.b_out(b_out),
.a_out(a_out),
.r_tex_out(r_tex_out),
.g_tex_out(g_tex_out),
.b_tex_out(b_tex_out),
.a_tex_out(a_tex_out),
.fragment_out_valid(fragment_out_valid),
.src(sink[0:3]) 
);

 pixel_shader_check  pixel_shader_check_uut(
         .clk(clk),
         .rst_n(rst_n),
         .s(s),
         .t(t),
         .matrix_A(matrix_A),
         .matrix_B(matrix_B),
         .matrix_C(matrix_C),
         .matrix_D(matrix_D),
         .matrix_E(matrix_E),
         .matrix_F(matrix_F),
         .matrix_G(matrix_G),
         .matrix_H(matrix_H),
         .fragment_valid(fragment_valid),
         
         .tex_addr(tex_addr),
         .tex_width(tex_width),
         .tex_height(tex_height),
         .wrap_mode_s(wrap_mode_s),
         .wrap_mode_t(wrap_mode_t),
         .r_tex(r_tex_out),
         .g_tex(g_tex_out),
         .b_tex(b_tex_out),
         .a_tex(a_tex_out),
         .fragment_tex_valid(fragment_out_valid),
         .bus_addr() ,
         .bus_cmd ( ) ,
         .bus_bl  (  ) ,
         .bus_dout() ,
         .bus_den ( ),
         .fragment_tex_shading_busy(fragment_tex_shading_busy),
         .l2_cache_busy(l2_cache_busy),
         .ram_addr (ram_addr[19:0] ),
         .ram_wrn  (ram_wrn  ),
         .ram_csn  (ram_csn  ),
         .ram_wdata(ram_wdata),
         .ram_rdata(ram_rdata)  
         );



initial
begin
    clk = 0;
    rst_n = 0;
    x = 0;
    #100
    rst_n = 1;
    #100000000;
    $finish;

end

always #2     clk = !clk;


initial
begin
    
	$fsdbDumpfile("pixel_shader_wave.fsdb");
	$fsdbDumpvars(0,tb);
end

reg [31:0] uv_counter;

always@(posedge clk or negedge rst_n)
    begin
        if(~rst_n)
           uv_counter <= 0;
        else if(tb.u_dut.u_texel_generate.u_addr_translate.uv_fifo_rd)
           uv_counter <= uv_counter + 1; 
    end  
reg [31:0] xy_counter;

always@(posedge clk or negedge rst_n)
    begin
        if(~rst_n)
           xy_counter <= 0;
        else if(tb.u_dut.u_uv_translate.xy_en)
           xy_counter <= xy_counter + 1; 
    end  


reg [31:0] st_counter;

always@(posedge clk or negedge rst_n)
    begin
        if(~rst_n)
           st_counter <= 0;
        else if(tb.u_dut.u_uv_translate.uv_en )
           st_counter <= st_counter + 1; 
    end  

always@(posedge clk or negedge rst_n)
    begin
        if(~rst_n)
           x <= 0;
        else if(fragment_valid)
           x <= x + 1; 
    end  

endmodule


